﻿namespace DomainServices.Tools.SharedTypes
{
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Reflection;

    internal class VirtualType : Type
    {
        private System.Reflection.Assembly _assembly;
        private Type _baseType;
        private List<MemberInfo> _declaredMembers;
        private string _name;
        private string _namespaceName;

        internal VirtualType(Type sourceType) : this(sourceType.Name, sourceType.Namespace, sourceType.Assembly, (sourceType.BaseType == null) ? null : ((Type) new VirtualType(sourceType.BaseType)))
        {
        }

        internal VirtualType(string name, string namespaceName, System.Reflection.Assembly assembly, Type baseType)
        {
            this._declaredMembers = new List<MemberInfo>();
            this._name = name;
            this._namespaceName = namespaceName;
            this._assembly = assembly;
            this._baseType = baseType;
        }

        internal void AddDeclaredMember(MemberInfo memberInfo)
        {
            this._declaredMembers.Add(memberInfo);
        }

        protected override TypeAttributes GetAttributeFlagsImpl()
        {
            return TypeAttributes.AutoLayout;
        }

        protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
        {
            return null;
        }

        public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr)
        {
            return new ConstructorInfo[0];
        }

        public override object[] GetCustomAttributes(bool inherit)
        {
            return new object[0];
        }

        public override object[] GetCustomAttributes(Type attributeType, bool inherit)
        {
            return new object[0];
        }

        public override Type GetElementType()
        {
            return null;
        }

        public override EventInfo GetEvent(string name, BindingFlags bindingAttr)
        {
            return null;
        }

        public override EventInfo[] GetEvents(BindingFlags bindingAttr)
        {
            return new EventInfo[0];
        }

        public override FieldInfo GetField(string name, BindingFlags bindingAttr)
        {
            return null;
        }

        public override FieldInfo[] GetFields(BindingFlags bindingAttr)
        {
            return new FieldInfo[0];
        }

        public override Type GetInterface(string name, bool ignoreCase)
        {
            return null;
        }

        public override Type[] GetInterfaces()
        {
            return new Type[0];
        }

        public override MemberInfo[] GetMembers(BindingFlags bindingAttr)
        {
            return this._declaredMembers.ToArray();
        }

        protected override MethodInfo GetMethodImpl(string name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers)
        {
            return null;
        }

        public override MethodInfo[] GetMethods(BindingFlags bindingAttr)
        {
            return this._declaredMembers.OfType<MethodInfo>().ToArray<MethodInfo>();
        }

        public override Type GetNestedType(string name, BindingFlags bindingAttr)
        {
            return null;
        }

        public override Type[] GetNestedTypes(BindingFlags bindingAttr)
        {
            return new Type[0];
        }

        public override PropertyInfo[] GetProperties(BindingFlags bindingAttr)
        {
            return new PropertyInfo[0];
        }

        protected override PropertyInfo GetPropertyImpl(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers)
        {
            return null;
        }

        protected override bool HasElementTypeImpl()
        {
            return false;
        }

        public override object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters)
        {
            throw new NotImplementedException();
        }

        protected override bool IsArrayImpl()
        {
            return false;
        }

        protected override bool IsByRefImpl()
        {
            return false;
        }

        protected override bool IsCOMObjectImpl()
        {
            return false;
        }

        public override bool IsDefined(Type attributeType, bool inherit)
        {
            return false;
        }

        protected override bool IsPointerImpl()
        {
            return false;
        }

        protected override bool IsPrimitiveImpl()
        {
            return false;
        }

        public override System.Reflection.Assembly Assembly
        {
            get
            {
                return this._assembly;
            }
        }

        public override string AssemblyQualifiedName
        {
            get
            {
                return this.FullName;
            }
        }

        public override Type BaseType
        {
            get
            {
                return this._baseType;
            }
        }

        public override string FullName
        {
            get
            {
                if (!string.IsNullOrEmpty(this.Namespace))
                {
                    return (this.Namespace + "." + this.Name);
                }
                return this.Name;
            }
        }

        public override Guid GUID
        {
            get
            {
                return new Guid();
            }
        }

        public override System.Reflection.Module Module
        {
            get
            {
                return null;
            }
        }

        public override string Name
        {
            get
            {
                return this._name;
            }
        }

        public override string Namespace
        {
            get
            {
                return this._namespaceName;
            }
        }

        public override Type UnderlyingSystemType
        {
            get
            {
                return this;
            }
        }
    }
}

